package HTTP

import (
	"SQL/FSDB"
	"logs"
	"regexp"
	"strconv"
)

//---------------------------------------------- helper func
func canConvertToInt(s string) (value int, ok bool) {
	val, err := strconv.Atoi(s)
	if err != nil {
		return -1, false
	}
	return val, true
}
func canConvertToInt64(s string) (value int64, ok bool) {
	val, err := strconv.ParseInt(s, 10, 64)
	if err != nil {
		return -1, false
	}
	return val, true
}
func checkPattern(pattern string, str string) (ok bool) {
	if ok, _ := regexp.MatchString(pattern, str); ok {
		return true
	}
	return false
}
func checkInt(str string) (ok bool) {
	pattern := "^[0-9]{1,8}$"
	if checkPattern(pattern, str) {
		return true
	}
	return false
}

//---------------------------------------------------is Valid
func isArgsEmpty(args ...string) (ok bool, errCode int, errMsg string) {

	for _, arg := range args {
		if len(arg) != 0 {
			return false, Success, ""
		}
	}
	return true, errInvalidEmptyArgs, mInvalidEmptyArgs
}
func isValidID(id string, idName string) (ok bool, errCode int, errMsg string) {

	pattern := "^[0-9]{5}$"
	if checkPattern(pattern, id) {
		switch idName {
		case "UserID":
			ok, errCode, errMsg = isExistUserID(id)
			return
		case "GroupID":
			ok, errCode, errMsg = isExistGroupID(id)
			return
		case "ObjectID":
			ok, errCode, errMsg = isExistObjectID(id)
			return
		case "MemberID":
			ok, errCode, errMsg = isExistMemberID(id)
			return
		default:
			return true, Success, ""
		}
	}
	return false, errInvalidID, mInvalidUserID
}
func isValidPwd(pwd string) (ok bool, errCode int, errMsg string) {

	pattern := "^[\\da-zA-Z-_\\.\\?\\!\\,\\@\\#\\$\\%\\^\\&\\*\\(\\)\\=\\+\\[\\]\\{\\}]{6,20}$"
	if checkPattern(pattern, pwd) {
		return true, Success, ""
	}
	return false, errInvalidPassword, mInvalidPassword
}
func isValidTime(time string) (ok bool, errCode int, errMsg string) {

	pattern := "^20[0-2][0-9]-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}$"
	if checkPattern(pattern, time) {
		return true, Success, ""
	}
	return false, errInvalidTime, mInvalidTime
}
func isValidNickname(nickname string) (ok bool, errCode int, errMsg string) {

	l := len(nickname)
	if l > 0 && l < 40 {
		return true, Success, ""
	}
	return false, errInvalidNickname, mInvalidNickname
}
func isValidIcon(icon string) (ok bool, errCode int, errMsg string) {

	l := len(icon)
	if l > 0 && l < 19 {
		return true, Success, ""
	}
	return false, errInvalidIcon, mInvalidIcon
}
func isValidCustomInfo(customInfo string) (ok bool, errCode int, errMsg string) {

	l := len(customInfo)
	if l < 1024 {
		return true, Success, ""
	}
	return false, errInvalidCustomInfo, mInvalidCustomInfo
}
func isValidPageIndex(index string) (ok bool, value int, errCode int, errMsg string) {

	if !checkInt(index) {
		return false, -1, errInvalidPageIndex, mInvalidPageIndex
	}
	if val, ok := canConvertToInt(index); ok {
		if val < 0 || val > 999999 {
			return false, -1, errInvalidPageSize, mInvalidPageIndex
		}
		return true, val, Success, ""
	}
	return false, -1, errInvalidPageIndex, mInvalidPageIndex
}
func isValidPageSize(size string) (ok bool, value int, errCode int, errMsg string) {

	if !checkInt(size) {
		return false, -1, errInvalidPageSize, mInvalidPageSize
	}
	if val, ok := canConvertToInt(size); ok {
		if val < 0 || val > 999 {
			return false, -1, errInvalidPageSize, mInvalidPageSize
		}
		return true, val, Success, ""
	}
	return false, -1, errInvalidPageSize, mInvalidPageSize
}
func isValidMsgContent(msg string) (ok bool, errCode int, errMsg string) {

	l := len(msg)
	if l < 2048 {
		return true, Success, ""
	}
	return false, errInvalidMsgContent, mInvalidMsgContent
}
func isValidBool(boolStr string) (ok bool, value bool, errCode int, errMsg string) {

	val, err := strconv.ParseBool(boolStr)
	if err != nil {
		return false, false, errInvalidBoolArg, mInvalidBoolArg
	}
	return true, val, Success, ""
}

//---------------------------------------------------is Exist

// // 增减群的时候，要对 fsValidGroupTable 进行更新
// var fsValidUserTable = map[string]bool{}
// var fsValidGroupTable = map[string]bool{}

func isExistObjectID(id string) (ok bool, errCode int, errMsg string) {

	// if _, isExist := fsValidUserTable[id]; isExist {
	// 	return true, Success, ""
	// }
	// if _, isExist := fsValidGroupTable[id]; isExist {
	// 	return true, Success, ""
	// }
	sql := `SELECT id 
			FROM objects 
			WHERE id = $1`
	rows, err := FSDB.Query(sql, id)
	defer rows.Close()
	if err != nil {
		logs.Print("isIDExist Query 出错，err:", err.Error())
		return false, errDBQueryFailed, err.Error()
	}
	if rows.Next() {
		var id string
		err := rows.Scan(&id)
		if err != nil {
			logs.Print("isIDExist rows.Scan出错，err:", err.Error())
			return false, errDBQueryFailed, err.Error()
		}
	} else {
		return false, errNotExistID, mNotExistObjectID
	}
	return true, Success, ""
}
func isExistUserID(id string) (ok bool, errCode int, errMsg string) {

	// if _, isExist := fsValidUserTable[id]; isExist {
	// 	return true, Success, ""
	// }
	sql := `SELECT id 
			FROM users 
			WHERE id = $1`
	rows, err := FSDB.Query(sql, id)
	defer rows.Close()
	if err != nil {
		logs.Print("isIDExist Query 出错，err:", err.Error())
		return false, errDBQueryFailed, err.Error()
	}
	if rows.Next() {
		var id string
		err := rows.Scan(&id)
		if err != nil {
			logs.Print("isIDExist rows.Scan出错，err:", err.Error())
			return false, errDBQueryFailed, err.Error()
		}
	} else {
		return false, errNotExistID, mNotExistUserID
	}
	// fsValidUserTable[id] = true
	return true, Success, ""
}
func isExistMangagerID(managerID string) (ok bool, errCode int, errMsg string) {

	if ok, errCode, errMsg = isValidID(managerID, "UserID"); !ok {
		return
	}
	sql := `SELECT id 
			FROM users 
			WHERE id = $1 AND ismanager=true`
	rows, err := FSDB.Query(sql, managerID)
	defer rows.Close()
	if err != nil {
		logs.Print("isIDExist Query 出错，err:", err.Error())
		return false, errDBQueryFailed, err.Error()
	}
	if rows.Next() {
		var id string
		err := rows.Scan(&id)
		if err != nil {
			logs.Print("isIDExist rows.Scan出错，err:", err.Error())
			return false, errDBQueryFailed, err.Error()
		}
	} else {
		return false, errInvalidManager, mInvalidManager
	}
	// fsValidUserTable[id] = true
	return true, Success, ""
}
func isExistTalkerID(userID string, talkerID string, talkerIsUser bool) (ok bool, errCode int, errMsg string) {

	if !talkerIsUser {
		ok, errCode, errMsg = isExistGroupID(talkerID)
		if errCode != Success {
			return
		}
		ok, errCode, errMsg = isExistUserInGroup(userID, talkerID)
		return
	}
	ok, errCode, errMsg = isExistUserID(talkerID)
	if errCode == errNotExistID {
		errMsg = mNotExistTalkerID
	}
	return
}
func isExistMemberID(id string) (ok bool, errCode int, errMsg string) {
	ok, errCode, errMsg = isExistUserID(id)
	if errCode == errNotExistID {
		errMsg = mNotExistMemberID
	}
	return
}
func isExistGroupID(id string) (ok bool, errCode int, errMsg string) {

	// if _, isExist := fsValidGroupTable[id]; isExist {
	// 	return true, Success, ""
	// }
	sql := `SELECT id 
			FROM groups 
			WHERE id = $1`
	rows, err := FSDB.Query(sql, id)
	defer rows.Close()
	if err != nil {
		logs.Print("isIDExist Query 出错，err:", err.Error())
		return false, errDBQueryFailed, err.Error()
	}
	if rows.Next() {
		var id string
		err := rows.Scan(&id)
		if err != nil {
			logs.Print("isIDExist rows.Scan出错，err:", err.Error())
			return false, errDBQueryFailed, err.Error()
		}
	} else {
		return false, errNotExistID, mNotExistGroupID
	}
	// fsValidGroupTable[id] = true
	return true, Success, ""
}
func isExistUserInGroup(userID string, groupID string) (ok bool, errCode int, errMsg string) {

	sql := `SELECT userid 
			FROM members
			WHERE userid = $1 AND groupid = $2`
	rows, err := FSDB.Query(sql, userID, groupID)
	defer rows.Close()
	if err != nil {
		logs.Print("isIDExist Query 出错，err:", err.Error())
		return false, errDBQueryFailed, err.Error()
	}
	if rows.Next() {
		var id string
		err := rows.Scan(&id)
		if err != nil {
			logs.Print("isIDExist rows.Scan出错，err:", err.Error())
			return false, errDBQueryFailed, err.Error()
		}
	} else {
		return false, errNotExistUserInGroup, mNotExistUserInGroup
	}
	return true, Success, ""
}
